/**
 * 
 */
package fr.gfi.agraf.vue.action;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.interceptor.ParameterAware;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import org.springframework.util.CollectionUtils;

import com.opensymphony.xwork2.ActionSupport;

import fr.gfi.agraf.service.IDonneesCommunesService;
import fr.gfi.agraf.service.enumeration.CategorieComposantEnum;
import fr.gfi.agraf.utils.SpringFactory;
import fr.gfi.agraf.vue.action.login.LoginAction;
import fr.gfi.agraf.vue.bean.ComposantDTO;
import fr.gfi.agraf.vue.bean.DonneesCommunesFront;
import fr.gfi.agraf.vue.bean.NotificationDTO;
import fr.gfi.agraf.vue.bean.ProfilDTO;
import fr.gfi.agraf.vue.bean.UtilisateurDTO;

/**
 * @author Fw
 * 
 */
public abstract class AbstractApplicationSupportAction extends ActionSupport implements SessionAware,
		ServletRequestAware, ParameterAware, ServletResponseAware {

	/**
	 * Généré par Java
	 */
	private static final long serialVersionUID = -361729050040781297L;

	/**
	 * Variable d'interuption de session expiré
	 */
	public final static String SESSION_EXPIREE = "sessionExpiree";

	/**
	 * Identifiant du service des données communes
	 */
	public final static String DATA_SERVICE = "DonneesCommunesService";

	/**
	 * La session de l'utilisateur connecté
	 */
	protected Map<String, Object> sessionMap;

	/**
	 * Les parametres de requete
	 */
	private Map<String, String[]> parameters;

	/**
	 * La requete
	 */
	private HttpServletRequest servletRequest = null;

	/**
	 * La reponse
	 */
	private HttpServletResponse servletResponse = null;

	// Ici commence les attributs propres à la partie commune de l'application

	/**
	 * Le bean de l'utilisateur connecté
	 */
	private UtilisateurDTO utilisateurConnecte;

	/**
	 * Le libelle affiché en haut concernant l'utilisateur connecté
	 */
	private String libelleUtilisateurConnecte;

	/**
	 * profil que l'utilisateur a choisi au démarage de l'application s'il en a
	 * plusieurs
	 */
	protected ProfilDTO profilConnecte;

	/**
	 * Contient les composants de l'utilisateur selon le profil choisi
	 */
	private Map<CategorieComposantEnum, List<ComposantDTO>> mapComposantUtilisateur;

	/**
	 * Contient toutes les notifications non lues de l'utilisateur
	 */
	private List<NotificationDTO> listeNotificationNonLues;

	/**
	 * La liste des notifications récentes
	 */
	private List<NotificationDTO> listeNotificationsRecentes;

	/**
	 * Boolean testant s'il existe des notifications ou non
	 */
	private boolean notifNonVues;

	/**
	 * Liste des composants IHM propre à l'utilisateur connecté
	 */
	private List<ComposantDTO> listeComposantsIhm;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.opensymphony.xwork2.ActionSupport#execute()
	 */
	@Override
	public String execute() throws Exception {
		utilisateurConnecte = (UtilisateurDTO) sessionMap.get(LoginAction.UTILISATEUR);
		profilConnecte = (ProfilDTO) sessionMap.get(LoginAction.PROFIL_CONNECTE);
		if (utilisateurConnecte == null || profilConnecte == null) {
			return SESSION_EXPIREE;
		}
		// TODO Gerer si droit sur la page
		libelleUtilisateurConnecte = buildLibelleUtilisateur();

		// Appel au service
		final IDonneesCommunesService dataService = (IDonneesCommunesService) SpringFactory
				.getApplicationContext().getBean(DATA_SERVICE);

		final DonneesCommunesFront data = dataService.getDonneesCommunes(profilConnecte.getId(),
				utilisateurConnecte.getId());
		mapComposantUtilisateur = data.getMapComposant();
		listeNotificationNonLues = data.getListeNotifications();
		if (!CollectionUtils.isEmpty(listeNotificationNonLues)) {
			notifNonVues = true;
		}
		listeNotificationsRecentes = data.getListeNotificationRecentes();
		listeComposantsIhm = data.getListeComposantIhm();

		return executeAction();
	}

	/**
	 * Renvoie true si l'utilisateur loggé possede les droits sur le composants
	 * dont l'id est passé en parametre
	 * 
	 * @param id
	 * @return
	 */
	public boolean existComposantIhm(final Long id) {
		boolean output = false;
		for (final ComposantDTO comp : listeComposantsIhm) {
			if (comp.getId().equals(id)) {
				output = true;
			}
		}
		return output;
	}

	/**
	 * construit le libelle affiché en haut de la page
	 * 
	 * @return
	 */
	private String buildLibelleUtilisateur() {
		final StringBuilder sb = new StringBuilder();
		sb.append(utilisateurConnecte.getPrenom());
		sb.append(" ");
		sb.append(utilisateurConnecte.getNom());
		sb.append(" -- ");
		sb.append(profilConnecte.getLibelle());
		return sb.toString();
	}

	/**
	 * Methode d'execution des actions etendue par cette classe
	 * 
	 * @return le forward voulu
	 * @throws Exception
	 */
	public abstract String executeAction() throws Exception;

	public void setSession(final Map<String, Object> session) {
		this.setSessionMap(session);
	}

	public void setParameters(final Map<String, String[]> parameters) {
		this.parameters = parameters;
	}

	public void setServletResponse(final HttpServletResponse servletResponse) {
		this.servletResponse = servletResponse;
	}

	public void setServletRequest(final HttpServletRequest servletRequest) {
		this.servletRequest = servletRequest;
	}

	public Map<String, String[]> getParameters() {
		return parameters;
	}

	public HttpServletRequest getServletRequest() {
		return servletRequest;
	}

	public HttpServletResponse getServletResponse() {
		return servletResponse;
	}

	public Map<String, Object> getSessionMap() {
		return sessionMap;
	}

	public void setSessionMap(final Map<String, Object> sessionMap) {
		this.sessionMap = sessionMap;
	}

	public UtilisateurDTO getUtilisateurConnecte() {
		return utilisateurConnecte;
	}

	public String getLibelleUtilisateurConnecte() {
		return libelleUtilisateurConnecte;
	}

	public void setLibelleUtilisateurConnecte(final String libelleUtilisateurConnecte) {
		this.libelleUtilisateurConnecte = libelleUtilisateurConnecte;
	}

	public ProfilDTO getProfilConnecte() {
		return profilConnecte;
	}

	public void setProfilConnecte(final ProfilDTO profilConnecte) {
		this.profilConnecte = profilConnecte;
	}

	public void setUtilisateurConnecte(final UtilisateurDTO utilisateurConnecte) {
		this.utilisateurConnecte = utilisateurConnecte;
	}

	public Map<CategorieComposantEnum, List<ComposantDTO>> getMapComposantUtilisateur() {
		return mapComposantUtilisateur;
	}

	public List<NotificationDTO> getListeNotificationNonLues() {
		return listeNotificationNonLues;
	}

	/**
	 * @return the listeNotificationsRecentes
	 */
	public List<NotificationDTO> getListeNotificationsRecentes() {
		return listeNotificationsRecentes;
	}

	/**
	 * @return the notifNonVues
	 */
	public boolean isNotifNonVues() {
		return notifNonVues;
	}

	/**
	 * @return the listeComposantsIhm
	 */
	public List<ComposantDTO> getListeComposantsIhm() {
		return listeComposantsIhm;
	}

}
